﻿//=====================================================================================
// All Rights Reserved , Copyright@ UBT 2016
//=====================================================================================

using System;
using System.Configuration;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;

namespace UBT.Encrypt.Tools
{
    /// <summary>
    /// 版 本：2.0
    /// 创 建：zhangpeng
    /// 日 期：2017-04-26 14:41
    /// 描 述：DES 加密、解密帮助类，加入深度加解密算法
    /// </summary>
    public class DESEncrypt
    {
        /// <summary>
        /// 密钥，必须8位
        /// </summary>
        private static readonly string StrKey = string.IsNullOrEmpty(ConfigurationManager.AppSettings["Key"]) ? "MJShanxi" : ConfigurationManager.AppSettings["Key"];
        /// <summary>
        /// 源字符串
        /// </summary>
        private static readonly string SourceStr = string.IsNullOrEmpty(ConfigurationManager.AppSettings["SourceStr"]) ? "s" : ConfigurationManager.AppSettings["SourceStr"];
        /// <summary>
        /// 替换字符串
        /// </summary>
        private static readonly string ReplaceStr = string.IsNullOrEmpty(ConfigurationManager.AppSettings["ReplaceStr"]) ? "mjshanxi" : ConfigurationManager.AppSettings["ReplaceStr"];

        #region DES加密
        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="text">要加密的字符串</param>
        /// <returns>以Base64格式返回的加密字符串</returns>
        public static string Encrypt(string text)
        {
            return Encrypt(text, StrKey);
        }
        /// <summary> 
        /// DES加密
        /// </summary> 
        /// <param name="text">要加密的字符串</param> 
        /// <param name="sKey">密钥，且必须8位</param> 
        /// <returns>以Base64格式返回的加密字符串</returns> 
        public static string Encrypt(string text, string sKey)
        {
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                byte[] inputByteArray;
                inputByteArray = Encoding.UTF8.GetBytes(text);
                des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    string str = Convert.ToBase64String(ms.ToArray());
                    ms.Close();
                    return str;
                }

            }

        }

        #endregion

        #region DES解密
        /// <summary>
        /// DES解密
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string Decrypt(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                return Decrypt(text, StrKey);
            }
            else
            {
                return "";
            }
        }
        /// <summary> 
        /// 解密数据 
        /// </summary> 
        /// <param name="text">要解密的以Base64</param> 
        /// <param name="sKey">密钥，且必须为8位</param> 
        /// <returns>已解密的字符串</returns> 
        public static string Decrypt(string text, string sKey)
        {
            if (text.Contains("Password"))//如果包含Password，表示没有加密
            {
                return text;
            }

            //确信当前字符串，是加密字符串
            if ((text.Length % 4) != 0)//因为加密后是base64，所以用4来求余进行验证
            {
                return text;
            }

            byte[] inputByteArray = Convert.FromBase64String(text);

            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();
                return Encoding.UTF8.GetString(ms.ToArray());
            }


        }

        #endregion

        #region 深度加密
        /// <summary>
        /// 深度加密
        /// </summary>
        /// <param name="pToEncrypt">要加密的字符串</param>
        /// <param name="sKey">密钥，且必须8位</param>
        /// <returns>以Base64格式返回的深度加密字符串</returns>
        public static string DepthEncrypt(string pToEncrypt, string sKey)
        {
            //一级加密
            string yetEncryStr = Encrypt(pToEncrypt, sKey);
            //二级加密
            string secondEncryStr = Regex.Replace(yetEncryStr, SourceStr, ReplaceStr);

            return secondEncryStr;
        }

        /// <summary>
        /// 深度加密
        /// </summary>
        /// <param name="pToEncrypt">要加密的字符串</param>
        /// <returns>以Base64格式返回的深度加密字符串</returns>
        public static string DepthEncrypt(string pToEncrypt)
        {
            //一级加密
            string yetEncryStr = Encrypt(pToEncrypt, StrKey);
            //二级加密
            string secondEncryStr = Regex.Replace(yetEncryStr, SourceStr, ReplaceStr);

            return secondEncryStr;
        }

        #endregion

        #region 深度解密
        /// <summary>
        /// 深度解密
        /// </summary>
        /// <param name="pToDecrypt">要解密的以Base64</param>
        /// <param name="sKey">密钥，且必须8位</param>
        /// <returns>已解密的字符串</returns>
        public static string DepthDecrypt(string pToDecrypt, string sKey)
        {
            //对原加密字符串，作特殊字符替换（一级解密）
            string secondDecryptStr = Regex.Replace(pToDecrypt, ReplaceStr, SourceStr);
            //二级解密
            var yetDecrytString = Decrypt(secondDecryptStr, sKey);

            return yetDecrytString;
        }

        /// <summary>
        /// 深度解密
        /// </summary>
        /// <param name="pToDecrypt">要解密的以Base64</param>
        /// <returns>已解密的字符串</returns>
        public static string DepthDecrypt(string pToDecrypt)
        {
            //对原加密字符串，作特殊字符替换（一级解密）
            string secondDecryptStr = Regex.Replace(pToDecrypt, ReplaceStr, SourceStr);
            //二级解密
            var yetDecrytString = Decrypt(secondDecryptStr, StrKey);

            return yetDecrytString;
        }
        #endregion
    }
}